home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
076-100
/
disk_077
/
rawsamples
/
uuencode.d
< prev
Wrap
Text File
|
1992-05-06
|
7KB
|
316 lines
/*
* uuencode.drc
* Encode a binary file into an ASCII representation that can be mailed
* around. No blanks are sent - graves (`) are used instead. If only one
* parameter is given on the run command, then that is the name of the
* file to endcode. It's name is used as the target machine name, and
* the encoded output is left in a file with the same name but with
* '.uue' appended. No check is made for file names too long. If a
* second parameter is given, it is the name to use for the target
* machine file name. Any path names are stripped off of all except the
* input file read and any explicit target machine name. Thus, the
* output file will be created in the current directory.
*
* This is a very early program, written before the Amiga version of Draco
* had an I/O library and include files. Hence this source file is completely
* self contained (except for the interface routines and assembler support).
*/
uint
BUFF_SIZE = 10000, /* nice and big */
MAX_BYTES = 45; /* maximum bytes per encoded line */
ulong
MODE_READ = 1005,
MODE_WRITE = 1006;
type FileHandle_t = ulong;
extern
OpenDosLibrary(ulong version)*char,
CloseDosLibrary()void,
Output()FileHandle_t,
GetPars(*ulong pLen; **char pPtr)void,
DeleteFile(*char name)void,
Open(*char name; ulong mode)FileHandle_t,
Close(FileHandle_t fd)void,
Read(FileHandle_t fd; *byte buffer; ulong length)ulong,
Write(FileHandle_t fd; *char buffer; ulong length)ulong,
Exit(ulong status)void;
FileHandle_t StdOut, InFd, OutFd;
[BUFF_SIZE] byte InBuff; /* buffer for input binary file */
[BUFF_SIZE] char OutBuff; /* buffer for output ASCII file */
uint InMax, InPos, OutPos; /* buffer positions and count */
bool Eof; /* true => end-of-file on input */
ulong ParLen; /* used for parameter scanning */
*char ParPtr;
/*
* writeString - write a string to standard output.
*/
proc writeString(*char mess)void:
*char p;
p := mess;
while p* ~= '\e' do
p := p + 1;
od;
if Write(StdOut, mess, p - mess) ~= p - mess then
Exit(40);
fi;
corp;
/*
* flush -
* Flush the contents of the output buffer to the output file.
*/
proc flush()void:
if OutPos ~= 0 then
if Write(OutFd, &OutBuff[0], OutPos) ~= OutPos then
writeString("Error on write - aborting.\n");
Exit(30);
fi;
OutPos := 0;
fi;
corp;
/*
* addChar -
* Add a single character to the output file, flushing if needed.
*/
proc addChar(char ch)void:
OutBuff[OutPos] := ch;
OutPos := OutPos + 1;
if OutPos = BUFF_SIZE then
flush();
fi;
corp;
/*
* addString -
* Add a string to the output file, using 'addChar'.
*/
proc addString(*char st)void:
while st* ~= '\e' do
addChar(st*);
st := st + 1;
od;
corp;
/*
* encodeByte -
* Encode a six-bit value as an ASCII char and add it to the output.
* The main function is to replace blanks by graves.
*/
proc encodeByte(byte b)void:
addChar(if b = 0 then '`' else b + ' ' fi);
corp;
/*
* getByte -
* Get the next byte from the input binary file.
*/
proc getByte()byte:
if InPos = InMax then
InPos := 0;
InMax := Read(InFd, &InBuff[0], BUFF_SIZE);
if InMax = 0 then
Eof := true;
fi;
fi;
InPos := InPos + 1;
InBuff[InPos - 1]
corp;
/*
* encode -
* Encode the already opened input file into the already opened output
* file, using the given remote system file name.
*/
proc encode(*char remFileName)void:
*char p;
[MAX_BYTES] byte buff;
uint i, len;
byte b1, b2, b3;
/* add the 'begin' line */
addString("begin 644 ");
addString(remFileName);
addChar('\n');
/* add the encoded binary file */
while not Eof do
/* get a bufferful (or however much is left to get) */
len := 0;
while not Eof and len ~= MAX_BYTES do
buff[len] := getByte();
if not Eof then
len := len + 1;
fi;
od;
/* first char on output line is encoded actual length */
encodeByte(len);
/* followed by up to MAX_BYTES * 4 / 3 characters of encoded data */
i := 0;
while i < len do
b1 := buff[i];
b2 := buff[i + 1];
b3 := buff[i + 2];
i := i + 3;
encodeByte(b1 >> 2);
encodeByte(b1 & 0x03 << 4 | b2 >> 4);
encodeByte(b2 & 0x0f << 2 | b3 >> 6);
encodeByte(b3 & 0x3f);
od;
/* and a newline */
addChar('\n');
od;
/* add the zero length terminator line so the UNIX version will live */
encodeByte(0);
addChar('\n');
/* add the 'end' line */
addString("end\n");
corp;
/*
* parBump -
* Move up one character in the command line tail.
*/
proc parBump()void:
ParPtr := ParPtr + 1;
ParLen := ParLen - 1;
corp;
/*
* parSkipSpace -
* Skip over any space in the command line tail.
*/
proc parSkipSpace()void:
while ParLen ~= 0 and
(ParPtr* = ' ' or ParPtr* = '\n' or ParPtr* = '\r') do
parBump();
od;
corp;
/*
* parGetName -
* Isolate a name from the command tail.
*/
proc parGetName()void:
while ParLen ~= 0 and ParPtr* ~= ' ' and ParPtr* ~= '\n' do
parBump();
od;
ParPtr* := '\e';
parBump();
corp;
/*
* main -
* The main program. Get the command line parameters, parse them, open
* files as needed and pass the remote file name to 'encode'.
*/
proc main()void:
*char inFileName, remFileName;
[60] char nameBuffer;
*char p, q;
if OpenDosLibrary(0) ~= nil then
StdOut := Output();
GetPars(&ParLen, &ParPtr);
parSkipSpace();
if ParLen = 0 then
writeString("usage: uuencode localFileName [remoteFileName]\n");
else
inFileName := ParPtr;
parGetName();
parSkipSpace();
/* find the final simple name of the given input name */
p := inFileName;
while p* ~= '\e' do
p := p + 1;
od;
while p ~= inFileName and p* ~= '/' do
p := p - 1;
od;
if p* = '/' then
p := p + 1;
fi;
if ParLen = 0 then
/* if no explicit remote file name is given, use the tail of
the input file name. */
remFileName := p;
else
remFileName := ParPtr;
parGetName();
fi;
/* make a copy of input name so that we can append .uue to it */
q := &nameBuffer[0];
while
q* := p*;
p* ~= '\e'
do
p := p + 1;
q := q + 1;
od;
p := ".uue";
while
q* := p*;
p* ~= '\e'
do
p := p + 1;
q := q + 1;
od;
/* open files, etc. */
InFd := Open(inFileName, MODE_READ);
if InFd = 0 then
writeString("Can't open input file '");
writeString(inFileName);
writeString("'\n");
Exit(10);
fi;
DeleteFile(&nameBuffer[0]);
OutFd := Open(&nameBuffer[0], MODE_WRITE);
if OutFd = 0 then
writeString("Can't open/create output file '");
writeString(&nameBuffer[0]);
writeString("'\n");
Close(InFd);
Exit(20);
fi;
/* initialize */
Eof := false;
InMax := 0;
InPos := 0;
OutPos := 0;
/* go encode the file */
encode(remFileName);
/* flush output buffer, and close files */
flush();
Close(OutFd);
Close(InFd);
fi;
CloseDosLibrary();
fi;
corp;